{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 搭建基于CBHG的拼音到汉字语言模型\n",
    "\n",
    "最近研究一下感觉用self-attention来对语言模型进行建模会更加不错，这里先做一个CBHG的tutorial吧\n",
    "\n",
    "- 数据处理\n",
    "- 模型搭建\n",
    "\n",
    "## 1. 数据处理\n",
    "- 读取数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(\"data/zh.tsv\", 'r', encoding='utf-8') as fout:\n",
    "    data = fout.readlines()[:100]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|████████████████████████████████████████████████████████████████████████████| 100/100 [00:00<00:00, 100150.53it/s]\n"
     ]
    }
   ],
   "source": [
    "from tqdm import tqdm\n",
    "\n",
    "inputs = []\n",
    "labels = []\n",
    "for i in tqdm(range(len(data))):\n",
    "    key, pny, hanzi = data[i].split('\\t')\n",
    "    inputs.append(pny.split(' '))\n",
    "    labels.append(hanzi.strip('\\n').split(' '))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[['lv4', 'shi4', 'yang2', 'chun1', 'yan1', 'jing3', 'da4', 'kuai4', 'wen2', 'zhang1', 'de', 'di3', 'se4', 'si4', 'yue4', 'de', 'lin2', 'luan2', 'geng4', 'shi4', 'lv4', 'de2', 'xian1', 'huo2', 'xiu4', 'mei4', 'shi1', 'yi4', 'ang4', 'ran2'], ['ta1', 'jin3', 'ping2', 'yao1', 'bu4', 'de', 'li4', 'liang4', 'zai4', 'yong3', 'dao4', 'shang4', 'xia4', 'fan1', 'teng2', 'yong3', 'dong4', 'she2', 'xing2', 'zhuang4', 'ru2', 'hai3', 'tun2', 'yi1', 'zhi2', 'yi3', 'yi1', 'tou2', 'de', 'you1', 'shi4', 'ling3', 'xian1'], ['pao4', 'yan3', 'da3', 'hao3', 'le', 'zha4', 'yao4', 'zen3', 'me', 'zhuang1', 'yue4', 'zheng4', 'cai2', 'yao3', 'le', 'yao3', 'ya2', 'shu1', 'de', 'tuo1', 'qu4', 'yi1', 'fu2', 'guang1', 'bang3', 'zi', 'chong1', 'jin4', 'le', 'shui3', 'cuan4', 'dong4'], ['ke3', 'shei2', 'zhi1', 'wen2', 'wan2', 'hou4', 'ta1', 'yi1', 'zhao4', 'jing4', 'zi', 'zhi3', 'jian4', 'zuo3', 'xia4', 'yan3', 'jian3', 'de', 'xian4', 'you4', 'cu1', 'you4', 'hei1', 'yu3', 'you4', 'ce4', 'ming2', 'xian3', 'bu4', 'dui4', 'cheng1'], ['qi1', 'shi2', 'nian2', 'dai4', 'mo4', 'wo3', 'wai4', 'chu1', 'qiu2', 'xue2', 'mu3', 'qin1', 'ding1', 'ning2', 'wo3', 'chi1', 'fan4', 'yao4', 'xi4', 'jue2', 'man4', 'yan4', 'xue2', 'xi2', 'yao4', 'shen1', 'zuan1', 'xi4', 'yan2']]\n",
      "\n",
      "[['绿', '是', '阳', '春', '烟', '景', '大', '块', '文', '章', '的', '底', '色', '四', '月', '的', '林', '峦', '更', '是', '绿', '得', '鲜', '活', '秀', '媚', '诗', '意', '盎', '然'], ['他', '仅', '凭', '腰', '部', '的', '力', '量', '在', '泳', '道', '上', '下', '翻', '腾', '蛹', '动', '蛇', '行', '状', '如', '海', '豚', '一', '直', '以', '一', '头', '的', '优', '势', '领', '先'], ['炮', '眼', '打', '好', '了', '炸', '药', '怎', '么', '装', '岳', '正', '才', '咬', '了', '咬', '牙', '倏', '地', '脱', '去', '衣', '服', '光', '膀', '子', '冲', '进', '了', '水', '窜', '洞'], ['可', '谁', '知', '纹', '完', '后', '她', '一', '照', '镜', '子', '只', '见', '左', '下', '眼', '睑', '的', '线', '又', '粗', '又', '黑', '与', '右', '侧', '明', '显', '不', '对', '称'], ['七', '十', '年', '代', '末', '我', '外', '出', '求', '学', '母', '亲', '叮', '咛', '我', '吃', '饭', '要', '细', '嚼', '慢', '咽', '学', '习', '要', '深', '钻', '细', '研']]\n"
     ]
    }
   ],
   "source": [
    "print(inputs[:5])\n",
    "print()\n",
    "print(labels[:5])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 构造输入输出词典"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████████████████████████████████████████████████████████████████████████| 100/100 [00:00<00:00, 9116.07it/s]\n",
      "100%|██████████████████████████████████████████████████████████████████████████████| 100/100 [00:00<00:00, 4774.61it/s]\n"
     ]
    }
   ],
   "source": [
    "def get_vocab(data):\n",
    "    vocab = ['<PAD>']\n",
    "    for line in tqdm(data):\n",
    "        for char in line:\n",
    "            if char not in vocab:\n",
    "                vocab.append(char)\n",
    "    return vocab\n",
    "\n",
    "pny2id = get_vocab(inputs)\n",
    "han2id = get_vocab(labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['<PAD>', 'lv4', 'shi4', 'yang2', 'chun1', 'yan1', 'jing3', 'da4', 'kuai4', 'wen2']\n",
      "['<PAD>', '绿', '是', '阳', '春', '烟', '景', '大', '块', '文']\n"
     ]
    }
   ],
   "source": [
    "print(pny2id[:10])\n",
    "print(han2id[:10])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- data index\n",
    "\n",
    "将字符symbol格式的文本数据通过字典转化为index形式的数字形式的表示。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████████████████████████████████████████████████████████████████████████| 100/100 [00:00<00:00, 5898.00it/s]\n",
      "100%|██████████████████████████████████████████████████████████████████████████████| 100/100 [00:00<00:00, 3931.01it/s]\n"
     ]
    }
   ],
   "source": [
    "input_num = [[pny2id.index(pny) for pny in line] for line in tqdm(inputs)]\n",
    "label_num = [[han2id.index(han) for han in line] for line in tqdm(labels)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 数据生成器\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[  1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  11  16  17\n",
      "   18   2   1  19  20  21  22  23  24  25  26  27   0   0   0]\n",
      " [ 28  29  30  31  32  11  33  34  35  36  37  38  39  40  41  36  42  43\n",
      "   44  45  46  47  48  49  50  51  49  52  11  53   2  54  20]\n",
      " [ 55  56  57  58  59  60  61  62  63  64  15  65  66  67  59  67  68  69\n",
      "   11  70  71  49  72  73  74  75  76  77  59  78  79  42   0]\n",
      " [ 80  81  82   9  83  84  28  49  85  86  75  87  88  89  39  56  90  11\n",
      "   91  92  93  92  94  95  92  96  97  98  32  99 100   0   0]]\n",
      "[[  1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  11  16  17\n",
      "   18   2   1  19  20  21  22  23  24  25  26  27   0   0   0]\n",
      " [ 28  29  30  31  32  11  33  34  35  36  37  38  39  40  41  42  43  44\n",
      "   45  46  47  48  49  50  51  52  50  53  11  54  55  56  57]\n",
      " [ 58  59  60  61  62  63  64  65  66  67  68  69  70  71  62  71  72  73\n",
      "   74  75  76  77  78  79  80  81  82  83  62  84  85  86   0]\n",
      " [ 87  88  89  90  91  92  93  50  94  95  81  96  97  98  39  59  99  11\n",
      "  100 101 102 101 103 104 105 106 107 108 109 110 111   0   0]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "def get_batch(input_data, label_data, batch_size):\n",
    "    batch_num = len(input_data) // batch_size\n",
    "    for k in range(batch_num):\n",
    "        begin = k * batch_size\n",
    "        end = begin + batch_size\n",
    "        input_batch = input_data[begin:end]\n",
    "        label_batch = label_data[begin:end]\n",
    "        max_len = max([len(line) for line in input_batch])\n",
    "        input_batch = np.array([line + [0] * (max_len - len(line)) for line in input_batch])\n",
    "        label_batch = np.array([line + [0] * (max_len - len(line)) for line in label_batch])\n",
    "        yield input_batch, label_batch\n",
    "        \n",
    "        \n",
    "batch = get_batch(input_num, label_num, 4)\n",
    "input_batch, label_batch = next(batch)\n",
    "print(input_batch)\n",
    "print(label_batch)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数据处理部分先到这里，有了词典和数据，就能将符号转化为数值形式的索引号了。"
   ]
  },
  {
   "attachments": {
    "1545013574%281%29.jpg": {
     "image/jpeg": "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"
    },
    "1545013753%281%29.jpg": {
     "image/jpeg": "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"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. 模型搭建\n",
    "- 模型结构如下：\n",
    "![1545013574%281%29.jpg](attachment:1545013574%281%29.jpg)\n",
    "\n",
    "- 其中CBHG结构如下：\n",
    "![1545013753%281%29.jpg](https://img-blog.csdnimg.cn/20190606152240528.?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzNDcyMTQ2,size_16,color_FFFFFF,t_70)\n",
    "\n",
    "CBHG模块由1-D convolution bank ，highway network ，bidirectional GRU 组成。\n",
    "它的功能是从输入中提取有价值的特征，有利于提高模型的泛化能力。这里直接借用原作者代码，给出简要介绍。\n",
    "\n",
    "### embedding层\n",
    "光有对应的id，没法很好的表征文本信息，这里就涉及到构造词向量，关于词向量不在说明，网上有很多资料，模型中使用词嵌入层，通过训练不断的学习到语料库中的每个字的词向量，代码如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def embed(inputs, vocab_size, num_units, zero_pad=True, scope=\"embedding\", reuse=None):\n",
    "    with tf.variable_scope(scope, reuse=reuse):\n",
    "        lookup_table = tf.get_variable('lookup_table',\n",
    "                                       dtype=tf.float32,\n",
    "                                       shape=[vocab_size, num_units],\n",
    "                                       initializer=tf.truncated_normal_initializer(mean=0.0, stddev=0.01))\n",
    "        if zero_pad:\n",
    "            lookup_table = tf.concat((tf.zeros(shape=[1, num_units]),\n",
    "                                      lookup_table[1:, :]), 0)\n",
    "    return tf.nn.embedding_lookup(lookup_table, inputs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Encoder pre-net module\n",
    "embeding layer之后是一个encoder pre-net模块，它有两个隐藏层，层与层之间的连接均是全连接；\n",
    "第一层的隐藏单元数目与输入单元数目一致，\n",
    "第二层的隐藏单元数目为第一层的一半；两个隐藏层采用的激活函数均为ReLu，并保持0.5的dropout来提高泛化能力 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def prenet(inputs, num_units=None, is_training=True, scope=\"prenet\", reuse=None, dropout_rate=0.2):\n",
    "    '''Prenet for Encoder and Decoder1.\n",
    "    Args:\n",
    "      inputs: A 2D or 3D tensor.\n",
    "      num_units: A list of two integers. or None.\n",
    "      is_training: A python boolean.\n",
    "      scope: Optional scope for `variable_scope`.\n",
    "      reuse: Boolean, whether to reuse the weights of a previous layer\n",
    "        by the same name.\n",
    "\n",
    "    Returns:\n",
    "      A 3D tensor of shape [N, T, num_units/2].\n",
    "    '''\n",
    "\n",
    "    with tf.variable_scope(scope, reuse=reuse):\n",
    "        outputs = tf.layers.dense(inputs, units=num_units[0], activation=tf.nn.relu, name=\"dense1\")\n",
    "        outputs = tf.layers.dropout(outputs, rate=dropout_rate, training=is_training, name=\"dropout1\")\n",
    "        outputs = tf.layers.dense(outputs, units=num_units[1], activation=tf.nn.relu, name=\"dense2\")\n",
    "        outputs = tf.layers.dropout(outputs, rate=dropout_rate, training=is_training, name=\"dropout2\")\n",
    "    return outputs  # (N, ..., num_units[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### conv bank\n",
    "输入序列首先会经过一个卷积层，注意这个卷积层，它有K个大小不同的1维的filter，其中filter的大小为1,2,3…K。\n",
    "这些大小不同的卷积核提取了长度不同的上下文信息。其实就是n-gram语言模型的思想，K的不同对应了不同的gram, \n",
    "例如unigrams, bigrams, up to K-grams，然后，将经过不同大小的k个卷积核的输出堆积在一起\n",
    "（注意：在做卷积时，运用了padding，因此这k个卷积核输出的大小均是相同的），\n",
    "也就是把不同的gram提取到的上下文信息组合在一起，下一层为最大池化层，stride为1，width为2。\n",
    "- 定义一个卷积层"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def conv1d(inputs,\n",
    "       filters=None,\n",
    "       size=1,\n",
    "       rate=1,\n",
    "       padding=\"SAME\",\n",
    "       use_bias=False,\n",
    "       activation_fn=None,\n",
    "       scope=\"conv1d\",\n",
    "       reuse=None):\n",
    "    '''\n",
    "    Args:\n",
    "      inputs: A 3-D tensor with shape of [batch, time, depth].\n",
    "      filters: An int. Number of outputs (=activation maps)\n",
    "      size: An int. Filter size.\n",
    "      rate: An int. Dilation rate.\n",
    "      padding: Either `same` or `valid` or `causal` (case-insensitive).\n",
    "      use_bias: A boolean.\n",
    "      scope: Optional scope for `variable_scope`.\n",
    "      reuse: Boolean, whether to reuse the weights of a previous layer\n",
    "        by the same name.\n",
    "\n",
    "    Returns:\n",
    "      A masked tensor of the same shape and dtypes as `inputs`.\n",
    "    '''    \n",
    "    with tf.variable_scope(scope):\n",
    "        if padding.lower() == \"causal\":\n",
    "            # pre-padding for causality\n",
    "            pad_len = (size - 1) * rate  # padding size\n",
    "            inputs = tf.pad(inputs, [[0, 0], [pad_len, 0], [0, 0]])\n",
    "            padding = \"valid\"\n",
    "\n",
    "        if filters is None:\n",
    "            filters = inputs.get_shape().as_list[-1]\n",
    "\n",
    "        params = {\"inputs\": inputs, \"filters\": filters, \"kernel_size\": size,\n",
    "                  \"dilation_rate\": rate, \"padding\": padding, \"activation\": activation_fn,\n",
    "                  \"use_bias\": use_bias, \"reuse\": reuse}\n",
    "\n",
    "        outputs = tf.layers.conv1d(**params)\n",
    "    return outputs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 由不同kernel size的卷积，组合而成的卷积块\n",
    "\n",
    "参数为：\n",
    "\n",
    "1. N: batch size\n",
    "1. T: time steps\n",
    "1. C: embedding hidden units"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def conv1d_banks(inputs, num_units=None, K=16, is_training=True, scope=\"conv1d_banks\", reuse=None):\n",
    "    '''Applies a series of conv1d separately.\n",
    "\n",
    "    Args:\n",
    "      inputs: A 3d tensor with shape of [N, T, C]\n",
    "      K: An int. The size of conv1d banks. That is,\n",
    "        The `inputs` are convolved with K filters: 1, 2, ..., K.\n",
    "      is_training: A boolean. This is passed to an argument of `batch_normalize`.\n",
    "\n",
    "    Returns:\n",
    "      A 3d tensor with shape of [N, T, K*Hp.embed_size//2].\n",
    "    '''\n",
    "    with tf.variable_scope(scope, reuse=reuse):\n",
    "        outputs = conv1d(inputs, num_units // 2, 1)  # k=1\n",
    "        for k in range(2, K + 1):  # k = 2...K\n",
    "            with tf.variable_scope(\"num_{}\".format(k)):\n",
    "                output = conv1d(inputs, num_units, k)\n",
    "                outputs = tf.concat((outputs, output), -1)\n",
    "        outputs = normalize(outputs, is_training=is_training,\n",
    "                            activation_fn=tf.nn.relu)\n",
    "    return outputs  # (N, T, Hp.embed_size//2*K)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### gru\n",
    "如果换成lstm有可能效果更好。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gru(inputs, num_units=None, bidirection=False, seqlen=None, scope=\"gru\", reuse=None):\n",
    "    '''Applies a GRU.\n",
    "\n",
    "    Args:\n",
    "      inputs: A 3d tensor with shape of [N, T, C].\n",
    "      num_units: An int. The number of hidden units.\n",
    "      bidirection: A boolean. If True, bidirectional results\n",
    "        are concatenated.\n",
    "      scope: Optional scope for `variable_scope`.\n",
    "      reuse: Boolean, whether to reuse the weights of a previous layer\n",
    "        by the same name.\n",
    "\n",
    "    Returns:\n",
    "      If bidirection is True, a 3d tensor with shape of [N, T, 2*num_units],\n",
    "        otherwise [N, T, num_units].\n",
    "    '''\n",
    "    with tf.variable_scope(scope, reuse=reuse):\n",
    "        if num_units is None:\n",
    "            num_units = inputs.get_shape().as_list[-1]\n",
    "\n",
    "        cell = tf.contrib.rnn.GRUCell(num_units)\n",
    "        if bidirection:\n",
    "            cell_bw = tf.contrib.rnn.GRUCell(num_units)\n",
    "            outputs, _ = tf.nn.bidirectional_dynamic_rnn(cell, cell_bw, inputs,\n",
    "                                                         sequence_length=seqlen,\n",
    "                                                         dtype=tf.float32)\n",
    "            return tf.concat(outputs, 2)\n",
    "        else:\n",
    "            outputs, _ = tf.nn.dynamic_rnn(cell, inputs,\n",
    "                                           sequence_length=seqlen,\n",
    "                                           dtype=tf.float32)\n",
    "\n",
    "    return outputs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### highwaynet\n",
    "下一层输入到highway layers，highway nets的每一层结构为：把输入同时放入到两个一层的全连接网络中，\n",
    "这两个网络的激活函数分别采用了ReLu和sigmoid函数，假定输入为input，ReLu的输出为output1，sigmoid的输出为output2，\n",
    "那么highway layer的输出为output=output1∗output2+input∗（1−output2)。论文中使用了4层highway layer。\n",
    "代码如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "def highwaynet(inputs, num_units=None, scope=\"highwaynet\", reuse=None):\n",
    "    '''Highway networks, see https://arxiv.org/abs/1505.00387\n",
    "    Args:\n",
    "      inputs: A 3D tensor of shape [N, T, W].\n",
    "      num_units: An int or `None`. Specifies the number of units in the highway layer\n",
    "             or uses the input size if `None`.\n",
    "      scope: Optional scope for `variable_scope`.\n",
    "      reuse: Boolean, whether to reuse the weights of a previous layer\n",
    "        by the same name.\n",
    "    Returns:\n",
    "      A 3D tensor of shape [N, T, W].\n",
    "    '''\n",
    "    if not num_units:\n",
    "        num_units = inputs.get_shape()[-1]\n",
    "\n",
    "    with tf.variable_scope(scope, reuse=reuse):\n",
    "        H = tf.layers.dense(inputs, units=num_units, activation=tf.nn.relu, name=\"dense1\")\n",
    "        T = tf.layers.dense(inputs, units=num_units, activation=tf.nn.sigmoid,\n",
    "                            bias_initializer=tf.constant_initializer(-1.0), name=\"dense2\")\n",
    "        C = 1. - T\n",
    "        outputs = H * T + inputs * C\n",
    "\n",
    "\n",
    "    return outputs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### batch normalize\n",
    "\n",
    "使用bn层，加速训练。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def normalize(inputs,\n",
    "              decay=.99,\n",
    "              epsilon=1e-8,\n",
    "              is_training=True,\n",
    "              activation_fn=None,\n",
    "              reuse=None,\n",
    "              scope=\"normalize\"):\n",
    "    '''Applies {batch|layer} normalization.\n",
    "\n",
    "    Args:\n",
    "      inputs: A tensor with 2 or more dimensions, where the first dimension has\n",
    "        `batch_size`. If type is `bn`, the normalization is over all but\n",
    "        the last dimension. Or if type is `ln`, the normalization is over\n",
    "        the last dimension. Note that this is different from the native\n",
    "        `tf.contrib.layers.batch_norm`. For this I recommend you change\n",
    "        a line in ``tensorflow/contrib/layers/python/layers/layer.py`\n",
    "        as follows.\n",
    "        Before: mean, variance = nn.moments(inputs, axis, keep_dims=True)\n",
    "        After: mean, variance = nn.moments(inputs, [-1], keep_dims=True)\n",
    "      type: A string. Either \"bn\" or \"ln\".\n",
    "      decay: Decay for the moving average. Reasonable values for `decay` are close\n",
    "        to 1.0, typically in the multiple-nines range: 0.999, 0.99, 0.9, etc.\n",
    "        Lower `decay` value (recommend trying `decay`=0.9) if model experiences\n",
    "        reasonably good training performance but poor validation and/or test\n",
    "        performance.\n",
    "      is_training: Whether or not the layer is in training mode. W\n",
    "      activation_fn: Activation function.\n",
    "      scope: Optional scope for `variable_scope`.\n",
    "\n",
    "    Returns:\n",
    "      A tensor with the same shape and data dtype as `inputs`.\n",
    "    '''\n",
    "    inputs_shape = inputs.get_shape()\n",
    "    inputs_rank = inputs_shape.ndims\n",
    "\n",
    "    # use fused batch norm if inputs_rank in [2, 3, 4] as it is much faster.\n",
    "    # pay attention to the fact that fused_batch_norm requires shape to be rank 4 of NHWC.\n",
    "    inputs = tf.expand_dims(inputs, axis=1)\n",
    "    outputs = tf.contrib.layers.batch_norm(inputs=inputs,\n",
    "                                            decay=decay,\n",
    "                                            center=True,\n",
    "                                            scale=True,\n",
    "                                            updates_collections=None,\n",
    "                                            is_training=is_training,\n",
    "                                            scope=scope,\n",
    "                                            zero_debias_moving_mean=True,\n",
    "                                            fused=True,\n",
    "                                            reuse=reuse)\n",
    "    outputs = tf.squeeze(outputs, axis=1)\n",
    "\n",
    "    if activation_fn:\n",
    "        outputs = activation_fn(outputs)\n",
    "    return outputs"
   ]
  },
  {
   "attachments": {
    "1545013574%281%29.jpg": {
     "image/jpeg": "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"
    },
    "1545013753%281%29.jpg": {
     "image/jpeg": "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"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 搭建模型\n",
    "由各个组件构成模型。\n",
    "- 模型结构如下：\n",
    "![1545013574%281%29.jpg](attachment:1545013574%281%29.jpg)\n",
    "\n",
    "- 其中CBHG结构如下：\n",
    "![1545013753%281%29.jpg](attachment:1545013753%281%29.jpg)\n",
    "\n",
    "- 模型代码如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Graph():\n",
    "    '''Builds a model graph'''\n",
    "\n",
    "    def __init__(self, arg):\n",
    "        tf.reset_default_graph()\n",
    "        self.pny_size = arg.pny_size\n",
    "        self.han_size = arg.han_size\n",
    "        self.embed_size = arg.embed_size\n",
    "        self.is_training = arg.is_training\n",
    "        self.num_highwaynet_blocks = arg.num_highwaynet_blocks\n",
    "        self.encoder_num_banks = arg.encoder_num_banks\n",
    "        self.lr = arg.lr\n",
    "        \n",
    "        self.x = tf.placeholder(tf.int32, shape=(None, None))\n",
    "        self.y = tf.placeholder(tf.int32, shape=(None, None))\n",
    "        \n",
    "        # Character Embedding for x\n",
    "        enc = embed(self.x, self.pny_size, self.embed_size, scope=\"emb_x\")\n",
    "        # Encoder pre-net\n",
    "        prenet_out = prenet(enc,\n",
    "                            num_units=[self.embed_size, self.embed_size // 2],\n",
    "                            is_training=self.is_training)  # (N, T, E/2)\n",
    "\n",
    "        # Encoder CBHG\n",
    "        ## Conv1D bank\n",
    "        enc = conv1d_banks(prenet_out,\n",
    "                            K=self.encoder_num_banks,\n",
    "                            num_units=self.embed_size // 2,\n",
    "                            is_training=self.is_training)  # (N, T, K * E / 2)\n",
    "\n",
    "        ## Max pooling\n",
    "        enc = tf.layers.max_pooling1d(enc, 2, 1, padding=\"same\")  # (N, T, K * E / 2)\n",
    "\n",
    "        ## Conv1D projections\n",
    "        enc = conv1d(enc, self.embed_size // 2, 5, scope=\"conv1d_1\")  # (N, T, E/2)\n",
    "        enc = normalize(enc, is_training=self.is_training,\n",
    "                            activation_fn=tf.nn.relu, scope=\"norm1\")\n",
    "        enc = conv1d(enc, self.embed_size // 2, 5, scope=\"conv1d_2\")  # (N, T, E/2)\n",
    "        enc = normalize(enc, is_training=self.is_training,\n",
    "                            activation_fn=None, scope=\"norm2\")\n",
    "        enc += prenet_out  # (N, T, E/2) # residual connections\n",
    "\n",
    "        ## Highway Nets\n",
    "        for i in range(self.num_highwaynet_blocks):\n",
    "            enc = highwaynet(enc, num_units=self.embed_size // 2,\n",
    "                                scope='highwaynet_{}'.format(i))  # (N, T, E/2)\n",
    "\n",
    "        ## Bidirectional GRU\n",
    "        enc = gru(enc, self.embed_size // 2, True, scope=\"gru1\")  # (N, T, E)\n",
    "\n",
    "        ## Readout\n",
    "        self.outputs = tf.layers.dense(enc, self.han_size, use_bias=False)\n",
    "        self.preds = tf.to_int32(tf.argmax(self.outputs, axis=-1))\n",
    "\n",
    "        if self.is_training:\n",
    "            self.loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=self.y, logits=self.outputs)\n",
    "            self.istarget = tf.to_float(tf.not_equal(self.y, tf.zeros_like(self.y)))  # masking\n",
    "            self.hits = tf.to_float(tf.equal(self.preds, self.y)) * self.istarget\n",
    "            self.acc = tf.reduce_sum(self.hits) / tf.reduce_sum(self.istarget)\n",
    "            self.mean_loss = tf.reduce_sum(self.loss * self.istarget) / tf.reduce_sum(self.istarget)\n",
    "\n",
    "            # Training Scheme\n",
    "            self.global_step = tf.Variable(0, name='global_step', trainable=False)\n",
    "            self.optimizer = tf.train.AdamOptimizer(learning_rate=self.lr)\n",
    "            self.train_op = self.optimizer.minimize(self.mean_loss, global_step=self.global_step)\n",
    "\n",
    "            # Summary\n",
    "            tf.summary.scalar('mean_loss', self.mean_loss)\n",
    "            tf.summary.scalar('acc', self.acc)\n",
    "            self.merged = tf.summary.merge_all()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 参数设定"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "def create_hparams():\n",
    "    params = tf.contrib.training.HParams(\n",
    "        # vocab\n",
    "        pny_size = 50,\n",
    "        han_size = 50,\n",
    "        # embedding size\n",
    "        embed_size = 300,\n",
    "        num_highwaynet_blocks = 4,\n",
    "        encoder_num_banks = 8,\n",
    "        lr = 0.001,\n",
    "        is_training = True)\n",
    "    return params\n",
    "\n",
    "arg = create_hparams()\n",
    "arg.pny_size = len(pny2id)\n",
    "arg.han_size = len(han2id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 模型训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From d:\\ProgramData\\Anaconda3\\lib\\site-packages\\tensorflow\\python\\util\\deprecation.py:497: calling conv1d (from tensorflow.python.ops.nn_ops) with data_format=NHWC is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "`NHWC` for data_format is deprecated, use `NWC` instead\n",
      "INFO:tensorflow:Restoring parameters from logs/model\n",
      "epochs 5 : average loss =  1.2706838726997376\n",
      "epochs 10 : average loss =  0.7730961179733277\n",
      "epochs 15 : average loss =  0.4291091418266296\n",
      "epochs 20 : average loss =  0.2579580122232437\n",
      "epochs 25 : average loss =  0.17582486391067506\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "\n",
    "epochs = 25\n",
    "batch_size = 4\n",
    "\n",
    "g = Graph(arg)\n",
    "\n",
    "saver =tf.train.Saver()\n",
    "with tf.Session() as sess:\n",
    "    merged = tf.summary.merge_all()\n",
    "    sess.run(tf.global_variables_initializer())\n",
    "    if os.path.exists('logs/model.meta'):\n",
    "        saver.restore(sess, 'logs/model')\n",
    "    writer = tf.summary.FileWriter('tensorboard/lm', tf.get_default_graph())\n",
    "    for k in range(epochs):\n",
    "        total_loss = 0\n",
    "        batch_num = len(input_num) // batch_size\n",
    "        batch = get_batch(input_num, label_num, batch_size)\n",
    "        for i in range(batch_num):\n",
    "            input_batch, label_batch = next(batch)\n",
    "            feed = {g.x: input_batch, g.y: label_batch}\n",
    "            cost,_ = sess.run([g.mean_loss,g.train_op], feed_dict=feed)\n",
    "            total_loss += cost\n",
    "            if (k * batch_num + i) % 10 == 0:\n",
    "                rs=sess.run(merged, feed_dict=feed)\n",
    "                writer.add_summary(rs, k * batch_num + i)\n",
    "        if (k+1) % 5 == 0:\n",
    "            print('epochs', k+1, ': average loss = ', total_loss/batch_num)\n",
    "    saver.save(sess, 'logs/model')\n",
    "    writer.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 模型推断"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from logs/model\n",
      "输入测试拼音: lv4 shi4 yang2 chun1 yan1 jing3 da4 kuai4 wen2 zhang1 de di3 se4 si4 yue4 de lin2 luan2 geng4 shi4 lv4 de2 xian1 huo2 xiu4 mei4 shi1 yi4 ang4 ran2\n",
      "绿是阳春烟景大块文章的底色四月的林峦更是绿得鲜秀秀秀然回债权\n",
      "输入测试拼音: exit\n"
     ]
    }
   ],
   "source": [
    "arg.is_training = False\n",
    "\n",
    "g = Graph(arg)\n",
    "\n",
    "saver =tf.train.Saver()\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    saver.restore(sess, 'logs/model')\n",
    "    while True:\n",
    "        line = input('输入测试拼音: ')\n",
    "        if line == 'exit': break\n",
    "        line = line.strip('\\n').split(' ')\n",
    "        x = np.array([pny2id.index(pny) for pny in line])\n",
    "        x = x.reshape(1, -1)\n",
    "        preds = sess.run(g.preds, {g.x: x})\n",
    "        got = ''.join(han2id[idx] for idx in preds[0])\n",
    "        print(got)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}